/**
 * 
 */
package org.dragonfire.dasm.preprocessor.blockDefs;

import java.util.ArrayList;

import org.dragonfire.dasm.Command;
import org.dragonfire.dasm.instr.Macro;
import org.dragonfire.dasm.preprocessor.Block;
import org.dragonfire.dasm.preprocessor.BlockDef;
import org.dragonfire.dasm.preprocessor.Preprocessor;
import org.dragonfire.util.DArray;

/**
 * @author Darth Android
 * @date Jul 13, 2007
 */
public class MacroBlockDef extends BlockDef {

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.dragonfire.dasm.preprocessor.BlockDef#createBlock(java.lang.String,
	 *      java.lang.String)
	 */
	@Override
	public Block createBlock(Preprocessor prep, Command c) {
		String[] params = c.getParams();
		String[] types = (String[]) DArray.subArray(params, 1, params.length);
		for (int i = 0; i < types.length; i++) {
			types[i] = prep.getCompiler().evalString(types[i]);
		}
		String name = prep.getCompiler().evalString(params[0]);
		return new MacroBlock(name, types);
	}

	public static class MacroBlock extends Block {

		private ArrayList<String> lines = new ArrayList<String>();
		private String name;
		private String[] paramTypes;

		/**
		 * @param name
		 * @param end
		 * @param personalDirectives
		 */
		public MacroBlock(String name, String[] paramTypes) {
			super("macro", "endmacro");
			if (paramTypes == null)
				paramTypes = new String[0];
			this.name = name;
			this.paramTypes = paramTypes;
		}

		public void currLine(String line) {
			lines.add(line);
		}

		public void parsePersonalDirective(Preprocessor prep, Command c) {
			String name = c.getName();
			if (name == null)
				throw new IllegalArgumentException("NAME may not be null!");
			if (name.equalsIgnoreCase(getName())) {
				prep.setParsing(false);
				prep.setBlocking(false);
			}
			else if (name.equalsIgnoreCase(getEnd())) {
				prep.setParsing(true);
				prep.setBlocking(true);
				Macro m = new Macro(this.name, this.paramTypes, lines.toArray(new String[lines.size()]));
				prep.getCompiler().getInstructions().addCommand(m);
			}
			super.parsePersonalDirective(prep, c);
		}
	}
}
